﻿#include "qmemoryinfoprovider.h"
#include <QProcess>
#include <QStringList>
#include <QDebug>

QMemoryInfoProvider::QMemoryInfoProvider(QObject *parent)
    : QObject(parent)
{
}

QList<QMemoryInfoProvider::MemoryDetails> QMemoryInfoProvider::getAllMemoryDetails() const {
#ifdef Q_OS_WIN
    return getMemoryDetailsWindows();
#elif defined(Q_OS_LINUX)
    return getMemoryDetailsLinux();
#else
    return {};
#endif
}

QList<QMemoryInfoProvider::MemoryDetails> QMemoryInfoProvider::getMemoryDetailsWindows() const {
    QList<MemoryDetails> memoryDetailsList;
    QProcess process;

    // Use WMI to get detailed information about each memory module.
    process.start("wmic", QStringList() << "memorychip" << "get" << "/format:list");
    process.waitForFinished();
    QString memoryInfo = process.readAllStandardOutput();
    QStringList memoryBlocks = memoryInfo.split("\r\r\n\r\r\n", Qt::SkipEmptyParts);
    foreach (const QString &block, memoryBlocks) {
        MemoryDetails details;
        details.manufacturer = block.section("\nManufacturer=", 1, 1).section('\n', 0, 0).simplified();
        details.partNumber = block.section("\nPartNumber=", 1, 1).section('\n', 0, 0).simplified();
        details.serialNumber = block.section("\nSerialNumber=", 1, 1).section('\n', 0, 0).simplified();
        int memoryType = block.section("\nMemoryType=", 1, 1).section('\n', 0, 0).toInt();
        // SMBIOSMemoryType can provide more specific information than MemoryType.
        int smbiosMemoryType = block.section("\nSMBIOSMemoryType=", 1, 1).section('\n', 0, 0).toInt();
        details.memoryType = memoryTypeToDescription(smbiosMemoryType != -1 ? smbiosMemoryType : memoryType);
        details.speed = block.section("\nSpeed=", 1, 1).section('\n', 0, 0).simplified() + " MHz";
        details.capacity = block.section("\nCapacity=", 1, 1).section('\n', 0, 0).simplified();

        if (!details.manufacturer.isEmpty()) { // Assuming at least the Manufacturer field should be present for valid entries.
            memoryDetailsList.append(details);
        }
    }

    return memoryDetailsList;
}

QList<QMemoryInfoProvider::MemoryDetails> QMemoryInfoProvider::getMemoryDetailsLinux() const {
    QList<MemoryDetails> memoryDetailsList;
    QProcess process;
    process.start("dmidecode", QStringList() << "-t" << "memory");
    process.waitForFinished();
    QString dmidecodeOutput = process.readAllStandardOutput();
    QStringList sections = dmidecodeOutput.split("Memory Device\n");

    foreach (const QString &section, sections) {
        if (section.contains("Size:")) { // Only consider sections with a size entry as they represent actual memory modules.
            MemoryDetails details;
            details.manufacturer = section.section("Manufacturer:", 1, 1).section('\n', 0, 0).simplified();
            details.partNumber = section.section("Part Number:", 1, 1).section('\n', 0, 0).simplified();
            details.serialNumber = section.section("Serial Number:", 1, 1).section('\n', 0, 0).simplified();
            details.memoryType = section.section("Type:", 1, 1).section('\n', 0, 0).simplified(); // This may need conversion to a human-readable format.
            details.speed = section.section("Speed:", 1, 1).section('\n', 0, 0).simplified();
            details.capacity = section.section("Size:", 1, 1).section('\n', 0, 0).simplified();

            memoryDetailsList.append(details);
        }
    }

    return memoryDetailsList;
}

// Helper function to convert memory type codes to human-readable descriptions
QString QMemoryInfoProvider::memoryTypeToDescription(int memoryType) const {
    switch(memoryType) {
        // 基础类型（SMBIOS标准定义）
        case 0x01: return "Other";
        case 0x02: return "Unknown";
        case 0x03: return "DRAM";
        case 0x04: return "EDRAM";
        case 0x05: return "VRAM";
        case 0x06: return "SRAM";
        case 0x07: return "RAM";
        case 0x08: return "ROM";
        case 0x09: return "FLASH";
        case 0x0A: return "EEPROM";
        case 0x0B: return "FEPROM";
        case 0x0C: return "EPROM";
        case 0x0D: return "CDRAM";
        case 0x0E: return "3DRAM";
        case 0x0F: return "SDRAM";
        case 0x10: return "SGRAM";
        case 0x11: return "RDRAM";
        case 0x12: return "DDR";
        case 0x13: return "DDR2";
        case 0x14: return "DDR2 FB-DIMM";
        case 0x15: return "DDR3";
        case 0x16: return "FBDIMM";
        case 0x17: return "DDR4";
        case 0x18: return "LPDDR";
        case 0x19: return "LPDDR2";
        case 0x1A: return "LPDDR3";
        case 0x1B: return "LPDDR4/LPDDR4X";  // LPDDR4X属于LPDDR4的变种
        case 0x1C: return "Logical NVDIMM";
        case 0x1D: return "HBM";
        case 0x1E: return "HBM2";
        case 0x1F: return "DDR5";
        case 0x20: return "LPDDR5";
        case 0x21: return "HBM3";

        // 兼容性扩展（非官方但常见）
        case 0x22: return "GDDR6";    // 常见于显卡
        case 0x23: return "GDDR7";    // 未来预留
        case 0xFE: return "Custom";   // 厂商自定义类型

        default:
            // 返回十六进制数值 + 原始十进制值（便于调试）
            return QString("0x%1 (%2)").arg(memoryType, 0, 16).arg(memoryType);
    }
}
